<template>
  <div
    v-if="row.type !== 'recall'"
    :class="['chat-item', { 'chat-item2': isSelf }]"
  >
    <div class="chat-left">
      <img :src="imageSrc" class="avatar" @error="handleImageError" />
    </div>
    <div class="chat-right">
      <div class="cr-top">
        <span class="cr-title">{{ row.fromInfo?.name }}</span>
        <span class="cr-time">{{ row.createTime }}</span>
      </div>
      <div class="chat-content">
        <div class="char-wrap">
          <div class="cr-content">
            <el-popover
              v-model:visible="row.contextMenuVisible"
              :placement="isSelf ? 'left-end' : 'right-end'"
              trigger="contextmenu"
              width="64"
              popper-style="min-width: 64px"
              @show="showContextMenu"
            >
              <template #reference>
                <div>
                  <div class="msg-content">
                    <!-- 系统推送的文本 -->
                    <div v-if="row.source === 'system' && row.type === 'text'">
                      <div class="text-title">
                        {{ message.title }}
                      </div>
                      <div class="text-content">{{ message.content }}</div>
                      <el-button
                        text
                        :title="$t('msgQueue.link')"
                        @click="handleLink"
                      >
                        <el-icon size="18px">
                          <i-ep-link />
                        </el-icon>
                        {{ $t('msgQueue.link') }}
                      </el-button>
                    </div>
                    <!-- 文本 -->
                    <div v-else-if="row.type === 'text'">
                      <div class="text-content">{{ message.content }}</div>
                    </div>
                    <!-- 链接文本 -->
                    <span v-if="row.type === 'link'">
                      <el-link
                        type="primary"
                        :underline="false"
                        :href="row.link"
                        target="_blank"
                        style="white-space: pre-wrap"
                        >{{ message.linekText }}</el-link
                      >
                    </span>
                    <!-- 图片 -->
                    <span v-if="row.type === 'photo'" class="img-wrap">
                      <el-image
                        class="img"
                        :src="message.url"
                        :zoom-rate="1.2"
                        :max-scale="7"
                        :min-scale="0.2"
                        :preview-src-list="[message.url]"
                        show-progress
                        :initial-index="0"
                        fit="cover"
                      />
                    </span>
                    <!-- 文件 -->
                    <div v-if="row.type === 'file'" class="file-wrap">
                      <img :src="fileIcon" class="file-icon" />
                      <div class="file-wrap-content">
                        <div class="file-wrap-top">
                          <span class="file-name">{{ message.name }}</span>
                        </div>
                        <div class="file-wrap-bottom">
                          <span class="file-size">{{
                            g_utils.transformByteData(message.size)
                          }}</span>
                          <el-icon
                            class="icon"
                            title="下载文件"
                            @click="downloadFile"
                            ><i-ep-Download
                          /></el-icon>
                        </div>
                      </div>
                    </div>
                  </div>
                  <!-- 创建订单 -->
                  <div v-if="row.type === 'interact'" style="margin-top: 5px">
                    <el-button size="small" text @click="handleCreateOrder">{{
                      message.button01.text
                    }}</el-button>
                  </div>
                </div>
              </template>
              <div v-if="row.source !== 'system'" class="cr-popover-btns">
                <span>
                  <el-button
                    link
                    text
                    type="primary"
                    id="pop-copy"
                    :data-clipboard-text="message.content"
                    @click="handleCopyClick"
                    >复制</el-button
                  >
                </span>
                <!-- <span>
                  <el-button link text type="primary" @click="handleDelete"
                    >删除</el-button
                  >
                </span> -->
                <!-- <span v-if="isSelf">
                  <el-button link text type="primary" @click="handleRecall"
                    >撤回</el-button
                  >
                </span> -->
                <span>
                  <el-button link text type="primary" @click="handleQuote"
                    >引用</el-button
                  >
                </span>
              </div>
            </el-popover>
          </div>
          <el-icon
            v-if="row.sending"
            class="loading-icon-wrapper"
            color="#999"
            :size="14"
          >
            <i-ep-Loading class="loading-icon" />
          </el-icon>
        </div>
        <QuoteView
          v-model="row.referenceMsg"
          :nickName="row.fromInfo?.name || ''"
          style="margin: 5px 0 0"
        />
      </div>
    </div>
  </div>
  <!-- 撤回 -->
  <div v-if="row.type === 'recall'" class="recall-wrapper">
    <span style="white-space: pre-wrap">你撤回了一条消息</span>
  </div>
</template>

<script setup>
import Clipboard from 'clipboard'
import QuoteView from './QuoteView.vue'
import fileIcon from '@/assets/file.png'
import avatarImg from '@/assets/avatar.png'
import { saveAs } from 'file-saver'

const props = defineProps({
  row: {
    type: Object,
    default: () => {}
  }
})

const { userInfo } = storeToRefs(useUserStore())
const emits = defineEmits(['menu', 'delete', 'recall', 'quote'])
const clipboard = ref(null)
const isSelf = computed(
  () => String(props.row.fromId) === String(userInfo.value.userId)
)
const imageSrc = computed(() => {
  return props.row?.fromInfo?.avatar || avatarImg
})
const message = computed(() => {
  let msg = props.row?.message || ''
  msg = msg.replace(/\n/g, '\\n') // 转义换行符
  return msg ? JSON.parse(msg) : {}
})

onMounted(() => {
  //
})

onUnmounted(() => {
  // 销毁 Clipboard 实例，避免内存泄漏
  if (clipboard.value) clipboard.value.destroy()
})

const handleImageError = e => {
  console.log('handleImageError')
  // 替换为备用图片
  e.target.src = avatarImg
}

const showContextMenu = e => {
  setTimeout(() => {
    emits('menu', props.row)
  })
}

const handleLink = _ => {
  try {
    const route = g_router.resolve({
      path: g_options.getOptionText(
        g_options.msgTypeOptions,
        message.value.type
      )
    })
    window.open(route.href, '_blank')
  } catch (error) {
    console.error('导航到路由时出错:', error)
  }
}

const downloadFile = _ => {
  if (g_utils.isExternal(message.value.url)) {
    g_https.get(message.value.url, {}, { responseType: 'blob' }).then(data => {
      saveAs(new Blob([data]), message.value.name)
    })
  } else {
    // 提取 base64 部分
    const base64Data = message.value.url.split(',')[1]
    // 转换为 Blob
    const byteCharacters = atob(base64Data)
    const byteArrays = []
    for (let i = 0; i < byteCharacters.length; i++) {
      byteArrays.push(byteCharacters.charCodeAt(i))
    }
    const blob = new Blob([new Uint8Array(byteArrays)])
    // 保存文件
    saveAs(blob, message.value.name)
  }
}

const handleCreateOrder = _ => {
  const route = g_router.resolve({
    path: '/fleet/carBooking',
    query: message.value.button01.params
  })
  window.open(route.href, '_blank')
}

// 点击按钮复制
const handleCopyClick = _ => {
  clipboard.value = new Clipboard('#pop-copy')
  console.log('clipboard.value', clipboard.value)
  clipboard.value.on('success', e => {
    props.row.contextMenuVisible = false
    ElMessage({
      message: g_t('public.successCopy'),
      type: 'success'
    })
    clipboard.value.destroy()
  })
  clipboard.value.on('error', e => {
    props.row.contextMenuVisible = false
    // 不支持复制
    ElMessage.error(g_t('public.errorCpoy'))
    clipboard.value.destroy()
  })
}

const handleDelete = _ => {
  ElMessageBox.confirm('删除该条消息?', '删除消息', {
    confirmButtonText: '删除',
    cancelButtonText: '取消',
    type: 'warning'
  })
    .then(() => {
      emits('delete', props.row)
    })
    .catch(() => {})
}

const handleRecall = _ => {
  props.row.contextMenuVisible = false
  emits('recall', props.row)
}

const handleQuote = _ => {
  props.row.contextMenuVisible = false
  emits('quote', props.row)
}
</script>

<style lang="scss" scoped>
.chat-item {
  overflow: auto;
  & + .chat-item {
    margin-top: 20px;
  }
  .chat-left {
    display: inline-flex;
    padding-top: 8px;
    vertical-align: top;
    .avatar {
      width: 50px;
      height: 50px;
      border-radius: 50%;
    }
  }
  .chat-right {
    display: inline-block;
    margin: 0 5px;
    .cr-top {
      line-height: 18px;
      .cr-title {
        font-size: 14px;
        font-weight: bold;
        color: #333;
      }
      .cr-time {
        margin: 0 5px;
        font-size: 12px;
        color: #999;
      }
    }
    .chat-content {
      max-width: 30vw;
      margin-top: 5px;
      .char-wrap {
        position: relative;
        display: flex;
        align-items: center;
        .loading-icon-wrapper {
          position: absolute;
          top: 50%;
          right: -5px;
          transform: translate(100%, -50%);
        }
      }
    }
    .cr-content {
      display: inline-flex;
      padding: 5px;
      font-size: 14px;
      color: #333;
      border-radius: 5px;
      background-color: #f0f0f0;
    }
  }
}
.chat-item.chat-item2 {
  text-align: right;
  .chat-left {
    float: right;
  }
  .chat-right {
    .cr-top {
      .cr-title {
        float: right;
      }
    }
    .chat-content {
      .char-wrap {
        display: flex;
        justify-content: flex-end;
        .loading-icon-wrapper {
          left: -5px;
          transform: translate(-100%, -50%);
        }
      }
    }
    .cr-content {
      text-align: left;
      background-color: #d1e3ff;
    }
    .quote-container {
      justify-content: flex-end;
      text-align: left;
    }
  }
}

.msg-content {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  .text-title {
    white-space: pre-wrap;
    padding-bottom: 5px;
    font-size: 14px;
    font-weight: bold;
    color: #333;
  }
  .text-content {
    white-space: pre-wrap;
  }
  .img-wrap {
    .img {
      display: block;
      max-width: 200px;
      max-height: 200px;
    }
  }
  .file-wrap {
    display: flex;
    align-items: flex-start;
    .file-icon {
      display: block;
      width: 64 * 0.75px;
      height: 64 * 0.75px;
    }
    .file-wrap-content {
      height: 100%;
      display: flex;
      justify-content: space-between;
      flex-direction: column;
      .file-wrap-top {
        min-width: 140px;
      }
      .file-wrap-bottom {
        display: flex;
        justify-content: space-between;
        padding-top: 5px;
        .file-size {
          font-size: 12px;
          color: #666;
        }
        .icon {
          cursor: pointer;
          font-size: 18px;
        }
      }
    }
  }
}

.cr-popover-btns {
  display: flex;
  flex-direction: column;
}

.loading-icon {
  animation: loadingAni 1s linear infinite;
}

@keyframes loadingAni {
  0% {
    transform: rotate(0deg);
  }

  100% {
    transform: rotate(180deg);
  }
}

.recall-wrapper {
  width: 100%;
  margin: 15px 0;
  text-align: center;
  font-size: 12px;
  color: #999;
}
</style>
